package org.example.netty.demo.chapter4;

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.util.CharsetUtil;
import org.example.netty.demo.common.Cmd;

import java.lang.reflect.Method;
import java.util.Arrays;

/**
 * @author ： minzhiwei
 * create by 2020/1/19 19:54
 * @description
 */
public class CmdHandler extends SimpleChannelInboundHandler<ByteBuf> {

    /**
     * Is called for each message of type {@link ByteBuf}.
     *
     * @param ctx the {@link ChannelHandlerContext} which this {@link SimpleChannelInboundHandler}
     *            belongs to
     * @param msg the message to handle
     * @throws Exception is thrown if an error occurred
     */
    @Override
    protected void channelRead0(ChannelHandlerContext ctx, ByteBuf msg) throws Exception {
        final String s = msg.toString(CharsetUtil.UTF_8);
        final String[] split = s.split("\\|");
        final String className = split[0];
        final String methodName = split[1];
        final String types = split[2];
        final String args = split[3];
        final Class<?> aClass = Class.forName(className);
        final String[] split1 = types.split("\\s");
        final Class<?>[] classes = Arrays.stream(split1).map(className1 -> {
            try {
                return Class.forName(className1);
            } catch (ClassNotFoundException e) {
                throw new RuntimeException(e);
            }
        }).toArray(Class<?>[]::new);
        final Method declaredMethod = aClass.getDeclaredMethod(methodName, classes);
        final String[] split2 = args.split("\\s");
        final Object[] as = new Object[split1.length];
        for (int i = 0; i < split1.length; i++) {
            final Class<?> aClass1 = classes[i];
            final String s2 = split2[i];
            if (aClass1 == int.class) {
                as[i] = Integer.parseInt(s2);

            } else {
                as[i] = s2;
            }
        }
        ctx.fireChannelRead(Cmd.builder()
                .clazz(aClass)
                .method(declaredMethod)
                .args(as)
                .build());
    }
}
